package control;

import java.util.ArrayList;
import java.util.Scanner;

import store.TaxCalculator;

import data.*;

import model.*;

public abstract class Register extends Station {

	public Register(ArrayList<Treat> treats, TaxCalculator calc) {
		super(treats,calc);
	}

		
	protected void interactWithUser(int choice) throws Exception {
		
		Treat treat = getTreatOrder(choice);
		getContainer(treat);
		getFlavors(treat);
		getToppings(treat);
		getPayment(treat);
		treats.add(treat);
	}

	
	private void getPayment(Treat treat) {
		System.out.printf("Your cost before tax is: %.2f\n", treat.getPrice());
		System.out.printf("Your treat total is $%.2f\n", calc.priceAfterTax(treat.getPrice()));
		System.out.println("How much would you like to pay?");
		Scanner in = new Scanner(System.in);
		float payment = in.nextFloat();
		
		System.out.printf("Your change is $%.2f\n", payment - treat.getPrice());
	}

	/**
	 * getContainer - gets the user's choice of container for the treat
	 * Preconditions: treat initialized as an instance of a concrete class
	 * Postconditions: Treat now has a container
	 * @param the Treat that will be getting a container
	 */
	public static void getContainer(Treat treat) throws Exception{
		ContainerFactory c = new ContainerFactory();
		String containerName;
		ArrayList<String> options = c.getContainerOptions(treat);
		if (options.size() > 1){
			int containerChoice = Menu.getMenuOption("What would you like your treat served in?", options);
			containerName = c.getContainerOptions(treat).get(containerChoice);
		} else {
			containerName = options.get(0);
		}
		
		String sizeName;
		if (c.getSizeOptions(containerName).size() == 1) { // don't ask if there's only one option
			sizeName = c.getSizeOptions(containerName).get(0);
		} else {
			int sizeChoice = Menu.getMenuOption("What size treat would you like?", c.getSizeOptions(containerName));
			sizeName = c.getSizeOptions(containerName).get(sizeChoice);
		}
		treat.setContainer(c.getContainer(containerName, sizeName));
	}
	
	/**
	 * getToppings - gets the user's choice of toppings for the treat
	 * Preconditions: treat initialized as an instance of a concrete class
	 *                treat has a container and size
	 * Postconditions: Treat now has all the toppings it will have
	 * @param the Treat that may be getting toppings
	 */
	public static void getToppings(Treat treat){
		int toppingChoice;
		ToppingFactory t = new ToppingFactory();
		ArrayList<Topping> toppingList = new ArrayList<Topping>();
		ArrayList<String> possibleToppings = t.getToppingOptions(treat);
		while (possibleToppings.size() > 0 && 
				Menu.yesOrNoMenu("Would you like to add a topping?")){
			toppingChoice = Menu.getMenuOption("What topping would you like", possibleToppings);
			toppingList.add(t.getTopping(possibleToppings.get(toppingChoice)));
			possibleToppings.remove(toppingChoice);
		}
		treat.setToppingList(toppingList);	
	}
	
	/**
	 * getFlavors - gets the user's choice of flavor for the treat
	 * Preconditions: treat initialized as an instance of a concrete class
	 *                treat has a container and size
	 * Postconditions: Treat now has all the flavors it will have
	 * @param the Treat that will be getting flavors
	 */
	public static void getFlavors(Treat treat) throws Exception{
		int flavorChoice;
		FlavorFactory f = new FlavorFactory();
		ArrayList<Flavor> flavorList = new ArrayList<Flavor>();
		flavorChoice = Menu.getMenuOption("What flavor or ingredient would you like?", f.getFlavorOptions(treat));
		flavorList.add(f.getFlavor(f.getFlavorOptions(treat).get(flavorChoice), treat));
		while (f.canHaveMultipleFlavors(treat) &&
				Menu.yesOrNoMenu("Would you like to add another flavor?")){
			flavorChoice = Menu.getMenuOption("What flavor would you like?", f.getFlavorOptions(treat));
			flavorList.add(f.getFlavor(f.getFlavorOptions(treat).get(flavorChoice), treat));
		}
		treat.setFlavorList(flavorList);
	}
	
	/**
	 * getTreat - gets the user's choice of treat
	 * Preconditions: None
	 * Postconditions: A concrete instance of Treat is returned
	 * @return AN initialized treat
	 */
	public abstract Treat getTreatOrder(int treatChoice);
	
	
}
